
#include "stdafx.h"
#include "EXIPAddressCtrl.h"


// CEXIPAddressCtrl

IMPLEMENT_DYNAMIC(CEXIPAddressCtrl, CIPAddressCtrl)

CEXIPAddressCtrl::CEXIPAddressCtrl()
{
	m_bSetBitmap = FALSE;
	m_nTopHeight = 0;
	m_nBottomHeight = 0;
	m_nLeftWidth = 0;
	m_nRightWidth = 0;
	m_nBkgndID = 0;
	m_nNumOfBgPics = 0;
	m_crBkgnd = RGB(255, 0, 255);
	m_bFocus = FALSE;
	m_nEditID = 0;
}

CEXIPAddressCtrl::~CEXIPAddressCtrl()
{
}


BEGIN_MESSAGE_MAP(CEXIPAddressCtrl, CIPAddressCtrl)
	ON_WM_SIZE()
	ON_WM_ERASEBKGND()
	ON_WM_DESTROY()
END_MESSAGE_MAP()



// CEXIPAddressCtrl message handlers

void CEXIPAddressCtrl::SetResSet(CEXBaseResSet* pResSet)
{
  m_pIPResSet = (CEXIPAddressCtrlResSet *)pResSet;

  SetFont(m_pIPResSet->m_font);

  if(m_pIPResSet->m_nType == IPADDRESS_CTRL)
    SetBitmaps(m_pIPResSet->m_arrImgId.GetAt(0), 
              m_pIPResSet->m_arrImgId.GetAt(0), 
              m_pIPResSet->m_nImg_DivideCnt, RGB(255,0,255));    
}

BOOL CEXIPAddressCtrl::InitBgBitmap(CBitmap & src, int index, int count)
{
	CDC * pDC = GetDC();

	CDC memDC; 
	memDC.CreateCompatibleDC(pDC);

	CDC srcDC;
	srcDC.CreateCompatibleDC(pDC);

	CBitmap* pOldBitmap1;
	pOldBitmap1 = srcDC.SelectObject(&src);

	BITMAP bmpinfo;
	src.GetBitmap(&bmpinfo);
	int bmpWidth = bmpinfo.bmWidth / count;
	int bmpHeight = bmpinfo.bmHeight;
	int orix = bmpWidth * (index < count ? index : 0);

	CRect rc;
	GetWindowRect(rc);
	rc.OffsetRect(-rc.left, -rc.top);

	CBitmap dist;
	dist.CreateCompatibleBitmap(pDC,rc.Width(),rc.Height());

	CBitmap* pOldBitmap2;
	pOldBitmap2 = memDC.SelectObject(&dist);

	memDC.FillSolidRect(rc, m_crBkgnd);

  if(!m_nTopHeight && !m_nRightWidth && !m_nLeftWidth && !m_nBottomHeight)
      memDC.StretchBlt(0, 0, rc.Width(), rc.Height() , &srcDC,
      orix, 0, bmpWidth, bmpHeight, SRCCOPY);
  else
  {
	  // entireimage
    memDC.TransparentBlt(m_nLeftWidth,
    m_nTopHeight,
    rc.Width()  - ( m_nLeftWidth + m_nRightWidth ) ,
    rc.Height() -  ( m_nTopHeight + m_nBottomHeight) ,
    &srcDC,
    orix + m_nLeftWidth,
    m_nTopHeight,
    bmpWidth - ( m_nLeftWidth + m_nRightWidth ) ,
    bmpHeight - ( m_nTopHeight + m_nBottomHeight ) , m_crBkgnd);

	  // topbar
	  memDC.TransparentBlt(m_nLeftWidth,0, rc.Width() - 
                        (m_nLeftWidth + m_nRightWidth), m_nTopHeight, &srcDC,
                        orix + m_nLeftWidth, 0, bmpWidth - ( m_nLeftWidth + 
                        m_nRightWidth), m_nTopHeight, m_crBkgnd);

	  // bottombar
	  memDC.TransparentBlt(m_nLeftWidth, rc.bottom-m_nBottomHeight, rc.Width() - 
                        ( m_nLeftWidth + m_nRightWidth), m_nBottomHeight,
                        &srcDC,orix + m_nLeftWidth,bmpHeight - m_nBottomHeight,
                        bmpWidth - ( m_nLeftWidth + m_nRightWidth), 
                        m_nBottomHeight, m_crBkgnd );

	  // sidebar
	  memDC.TransparentBlt(0,m_nTopHeight,m_nLeftWidth,rc.bottom - m_nTopHeight - 
                        m_nBottomHeight, &srcDC, orix, m_nTopHeight, 
                        m_nLeftWidth, bmpHeight - ( m_nTopHeight + 
                        m_nBottomHeight ), m_crBkgnd);

	  memDC.TransparentBlt(rc.right - m_nRightWidth ,m_nTopHeight,m_nRightWidth,
                        rc.bottom - m_nTopHeight - m_nBottomHeight, &srcDC, 
                        orix +  bmpWidth - m_nRightWidth,m_nTopHeight, 
                        m_nRightWidth, bmpHeight - m_nTopHeight - 
                        m_nBottomHeight , m_crBkgnd);

	  // lefttop,leftbottom,righttop,rightbottom
	  if(!memDC.BitBlt(0,0,m_nLeftWidth,m_nTopHeight, &srcDC, orix, 0, SRCCOPY))
		  return FALSE;

	  if(!memDC.BitBlt(0,rc.bottom - m_nBottomHeight, m_nLeftWidth, 
                    m_nBottomHeight, &srcDC, orix, bmpHeight - 
                    m_nBottomHeight, SRCCOPY))
		  return FALSE;

	  if(!memDC.BitBlt(rc.right - m_nRightWidth, 0, m_nRightWidth, m_nTopHeight, 
		                  &srcDC,orix + bmpWidth - m_nRightWidth, 0, SRCCOPY))
		  return FALSE;

	  if(!memDC.BitBlt(rc.right - m_nRightWidth, rc.bottom - m_nBottomHeight,
                    m_nRightWidth, m_nBottomHeight, &srcDC, orix + bmpWidth - 
                    m_nRightWidth, bmpHeight - m_nBottomHeight, SRCCOPY))
		  return FALSE;
  }

	if (!m_bmpBkgnd.GetSafeHandle())
		m_bmpBkgnd.CreateCompatibleBitmap(pDC, rc.Width()*count, rc.Height());

	CDC dcBkgnd;
	dcBkgnd.CreateCompatibleDC(pDC);

	CBitmap * pOldBitmap3 = dcBkgnd.SelectObject(&m_bmpBkgnd);

	dcBkgnd.BitBlt(rc.Width()*index, 0, rc.Width(), rc.Height(), 
                &memDC, 0, 0, SRCCOPY);

	srcDC.SelectObject(pOldBitmap1);
	memDC.SelectObject(pOldBitmap2);
	dcBkgnd.SelectObject(pOldBitmap3);

	ReleaseDC(pDC);
	ReleaseDC(&srcDC);
	ReleaseDC(&memDC);
	ReleaseDC(&dcBkgnd);

	return TRUE;
}

void CEXIPAddressCtrl::OnSize(UINT nType, int cx, int cy)
{
	CIPAddressCtrl::OnSize(nType, cx, cy);

	if (IsWindow(GetSafeHwnd()) && m_bSetBitmap)
	{
		SetBitmaps(m_nBkgndID, m_nEditID, m_nNumOfBgPics, m_crBkgnd, m_nTopHeight, 
              m_nBottomHeight, m_nLeftWidth, m_nRightWidth);
	}
}

BOOL CEXIPAddressCtrl::SetBitmaps(UINT nBkgndID, UINT nEditID, int nCount, 
                                  COLORREF crBkgnd, int nTopHeight /* = 0*/, 
                                  int nBottomHeight /* = 0*/, 
                                  int nLeftWidth /* = 0*/, 
                                  int nRightWidth /* = 0*/)
{
	m_nTopHeight = nTopHeight;
	m_nBottomHeight = nBottomHeight;
	m_nLeftWidth = nLeftWidth;
	m_nRightWidth = nRightWidth;
	m_nBkgndID = nBkgndID;
	m_nNumOfBgPics  = nCount;
	m_crBkgnd = crBkgnd;
	m_nEditID = nEditID;

	CBitmap bmpTemp;
	if( !bmpTemp.LoadBitmap(m_nBkgndID) )
		return FALSE;

	m_bmpBkgnd.DeleteObject();

	if( !InitBgBitmap( bmpTemp, normal, m_nNumOfBgPics) ) 
		return FALSE;

	if( !InitBgBitmap( bmpTemp, focus, m_nNumOfBgPics) )
		return FALSE;

	if( !InitBgBitmap( bmpTemp, select, m_nNumOfBgPics) )
		return FALSE;

	if( !InitBgBitmap( bmpTemp, disable, m_nNumOfBgPics) )
		return FALSE;

	HWND hFirst = ::FindWindowEx(GetSafeHwnd(), NULL, L"Edit", NULL);
	HWND hSecond = ::FindWindowEx(GetSafeHwnd(), hFirst, L"Edit", NULL);
	HWND hThird = ::FindWindowEx(GetSafeHwnd(), hSecond, L"Edit", NULL);
	HWND hFourth = ::FindWindowEx(GetSafeHwnd(), hThird, L"Edit", NULL);

	if (!IsWindow(m_edFirst.GetSafeHwnd()))
	{
		ASSERT(hFirst);
		if (!m_edFirst.SubclassWindow(hFirst))
			return FALSE;
	}

	VERIFY(m_edFirst.SetBgBitmaps(m_nEditID, 4, m_crBkgnd));

	if (!IsWindow(m_edSecond.GetSafeHwnd()))
	{
		ASSERT(hSecond);
		if (!m_edSecond.SubclassWindow(hSecond))
			return FALSE;
	}

	VERIFY(m_edSecond.SetBgBitmaps(m_nEditID, 4, m_crBkgnd));

	if (!IsWindow(m_edThird.GetSafeHwnd()))
	{
		ASSERT(hThird);
		if (!m_edThird.SubclassWindow(hThird))
			return FALSE;
	}

	VERIFY(m_edThird.SetBgBitmaps(m_nEditID, 4, m_crBkgnd));

	if (!IsWindow(m_edFourth.GetSafeHwnd()))
	{
		ASSERT(hFourth);
		if (!m_edFourth.SubclassWindow(hFourth))
			return FALSE;
	}

	VERIFY(m_edFourth.SetBgBitmaps(m_nEditID, 4, m_crBkgnd));

	m_bSetBitmap = TRUE;

	return TRUE;
}

BOOL CEXIPAddressCtrl::OnEraseBkgnd(CDC* pDC)
{
	if (m_bSetBitmap)
	{
		CWindowDC dc(this);
		DrawFrame(&dc);
		Invalidate(FALSE);
		return FALSE;
	}

	return CIPAddressCtrl::OnEraseBkgnd(pDC);
}

void CEXIPAddressCtrl::DrawFrame(CDC * pDC)
{
	if (!m_bSetBitmap)
		return;

	CRect rcWnd;
	GetWindowRect(rcWnd);
	ScreenToClient(rcWnd);

	CDC dcBkgnd;
	dcBkgnd.CreateCompatibleDC(pDC);

	CBitmap bmpBkgnd;
	bmpBkgnd.CreateCompatibleBitmap(pDC, rcWnd.Width(), rcWnd.Height());

	CBitmap * pOldBmpBkgnd = NULL;
	pOldBmpBkgnd = dcBkgnd.SelectObject(&bmpBkgnd);

	CDC dcImage;
	dcImage.CreateCompatibleDC(pDC);

	CBitmap* pOldBgBitmapImage = NULL;

	STATUS st;

	if (!IsWindowEnabled())
		st = disable;
	else if (GetFocus() == this)
		st = select;
	else if (m_bFocus)
		st = focus;
	else
		st = normal;

	pOldBgBitmapImage  = dcImage.SelectObject(&m_bmpBkgnd);

	dcBkgnd.BitBlt(0, 0, rcWnd.Width(), rcWnd.Height(), 
                &dcImage, rcWnd.Width()*st, 0, SRCCOPY);

	dcImage.SelectObject(pOldBgBitmapImage);

	pDC->BitBlt(0, 0, rcWnd.Width(), rcWnd.Height(), &dcBkgnd, 0, 0, SRCCOPY);
	dcBkgnd.SelectObject(pOldBmpBkgnd);

	CRect rcFirst;
	m_edFirst.GetWindowRect(rcFirst);
	ScreenToClient(rcFirst);

	CRect rcSecord;
	m_edSecond.GetWindowRect(rcSecord);
	ScreenToClient(rcSecord);

	CRect rcThird;
	m_edThird.GetWindowRect(rcThird);
	ScreenToClient(rcThird);

	int nOffX = (rcSecord.left - rcFirst.right) / 2;
	int nOffY = (rcSecord.bottom - rcFirst.top) / 2;

	CFont * pOldFont = pDC->SelectObject(GetFont());

	pDC->SetBkMode(TRANSPARENT);
	pDC->TextOut(rcFirst.right+nOffX, rcFirst.top, L".");
	pDC->TextOut(rcSecord.right+nOffX, rcSecord.top , L".");
	pDC->TextOut(rcThird.right+nOffX, rcThird.top, L".");

	pDC->SelectObject(pOldFont);
}

LRESULT CEXIPAddressCtrl::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
	if (message == WM_PAINT && m_bSetBitmap)
	{
		CPaintDC dc(this);
		CWindowDC dcWnd(this);
		DrawFrame(&dcWnd);
		return FALSE;
	}

	return CIPAddressCtrl::WindowProc(message, wParam, lParam);
}

void CEXIPAddressCtrl::OnDestroy()
{
	CIPAddressCtrl::OnDestroy();
  if(m_edThird && m_edFirst && m_edThird && m_edFourth)
	{
    m_edFirst.UnsubclassWindow();
	  m_edSecond.UnsubclassWindow();
	  m_edThird.UnsubclassWindow();
	  m_edFourth.UnsubclassWindow();
  }
}

BOOL CEXIPAddressCtrl::EnableWindow(BOOL bEnable /*= TRUE*/)
{
	m_edFirst.EnableWindow(bEnable);
	m_edSecond.EnableWindow(bEnable);
	m_edThird.EnableWindow(bEnable);
	m_edFourth.EnableWindow(bEnable);

	BOOL bRet = CIPAddressCtrl::EnableWindow(bEnable);

	RedrawWindow(NULL, NULL, RDW_ALLCHILDREN|RDW_INVALIDATE|RDW_UPDATENOW);

	return bRet;
}

void CEXIPAddressCtrl::SetFont(CFont* pFont, BOOL bRedraw /*= TRUE*/)
{
	LOGFONT lf = {0};
	pFont->GetLogFont(&lf);

	m_ft.DeleteObject();
	m_ft.CreateFontIndirect(&lf);

	CIPAddressCtrl::SetFont(&m_ft, bRedraw);
}